<template>
  <div class="w-full h-full flex">
    <div class="w-full h-full flex flex-col">
      <!-- 主播音视频 -->
      <div class="h-full border p-5">
        <live-video ref="liveVideoRefs" />
      </div>
      <!-- 相关操作 -->
      <div class="h-full border p-5 flex flex-col space-y-4 overflow-hidden">
        <div>
          <h2>当前操作</h2>
          <div class="flex space-x-4 items-center">
            <div>
              当前频道 Id
              <span class="text-lg bg-slate-400 p-1 rounded-sm">
                {{ channelId }}
              </span>
            </div>
            <div>
              本地用户 Id
              <span class="text-lg bg-slate-400 p-1 rounded-sm">
                {{ localUserId }}
              </span>
            </div>
            <el-button type="danger" @click="closeLiveFn">退出直播</el-button>
            <div v-if="userRole === 'host'">
              <el-button :disabled="!audio_mute.is_exist" @click="liveMicrophoneFn">
                静音 {{ audio_mute.is_mute ? "开" : "关" }}
              </el-button>
              <el-button :disabled="!video_mute.is_exist" @click="liveCameraFn">
                禁画 {{ video_mute.is_mute ? "开" : "关" }}
              </el-button>
            </div>
          </div>
        </div>
        <div class="flex-1 overflow-auto">
          <single-chat :user-id="localUserId" />
        </div>
      </div>
    </div>
    <!-- 聊天 -->
    <div class="w-96 border p-5">
      <group-chat :user-id="localUserId" />
    </div>
  </div>
</template>

<script lang="ts" setup>
import LiveVideo from "./LiveVideo.vue";
import GroupChat from "./GroupChat.vue";
import SingleChat from "./SingleChat.vue";
import AnyRTCLive, { AnyRTCLiveEvents } from "../../anyrtcLive/index";
import { InitOption } from "./liveType";
import { onMounted, onUnmounted, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
/**
 * close 组件关闭
 */
const live_emits = defineEmits(["close"]);

/** 退出直播 */
const closeLiveFn = () => {
  AnyRTCLive.logout();
  live_emits("close");
};

// 主播视频组件
const liveVideoRefs = ref();

// 主播麦克风关闭(静音切换)
const audio_mute = reactive({
  // 是否存在
  is_exist: true,
  // 进入前设置
  is_init: false,
  // 静音切换
  is_mute: false,
});
const liveMicrophoneFn = async () => {
  // 初始就静音(尚未打开麦克风)
  if (!audio_mute.is_init && audio_mute.is_mute && true) {
    await AnyRTCLive.startMicrophone();
    audio_mute.is_init = true;
    audio_mute.is_mute = false;
    liveVideoRefs.value.setAnchorAV(localUserId.value, "audio", true);
  } else {
    try {
      await AnyRTCLive.muteLocalMicrophone(!audio_mute.is_mute);
      audio_mute.is_mute = !audio_mute.is_mute;
      liveVideoRefs.value.setAnchorAV(
        localUserId.value,
        "audio",
        !audio_mute.is_mute
      );
    } catch (err) {
      const error = err as Error;
      ElMessage.warning("开关音频错误" + error.message);
    }
  }
};
// 主播关闭摄像头(禁画切换)
const video_mute = reactive({
  // 是否存在
  is_exist: true,
  // 进入前设置
  is_init: false,
  // 禁画切换
  is_mute: false,
});
const liveCameraFn = async () => {
  // 初始就静音(尚未打开麦克风)
  if (!video_mute.is_init && video_mute.is_mute && true) {
    await AnyRTCLive.startCameraPreview(localUserId.value);
    video_mute.is_init = true;
    video_mute.is_mute = false;
    liveVideoRefs.value.setAnchorAV(localUserId.value, "video", true);
  } else {
    try {
      await AnyRTCLive.muteLocalCamera(!video_mute.is_mute);
      video_mute.is_mute = !video_mute.is_mute;
      liveVideoRefs.value.setAnchorAV(
        localUserId.value,
        "video",
        !video_mute.is_mute
      );
    } catch (err) {
      const error = err as Error;
      ElMessage.warning("开关视频错误" + error.message);
    }
  }
};

// 当前用户Id
const localUserId = ref("");
// 用户角色
const userRole = ref("audience");
// 当前频道
const channelId = ref("");

/** 初始化 */
async function liveInit(options: InitOption) {
  // 获取设备
  const { cameraList, microphoneList, speakerList } =
    await AnyRTCLive.getMediaDeviceList();
  const {
    sdkAppId,
    roomId,
    role,
    rtcConfig,
    rtmConfig,
    rtcToken,
    rtmToken,
    userId,
    openCamera,
    openMicrophone,
  } = options;

  // 设置私有云
  AnyRTCLive.setParameters({
    rtcConfig,
    rtmConfig,
  });
  localUserId.value = userId;
  userRole.value = role;
  channelId.value = roomId;

  if (cameraList.length <= 0 && openCamera) {
    ElMessage.warning("未检测到摄像头却开启了");
    video_mute.is_exist = false;
  }
  if (microphoneList.length <= 0 && openMicrophone) {
    ElMessage.warning("未检测到麦克风却开启了");
    audio_mute.is_exist = false;
  }
  audio_mute.is_init = openMicrophone;
  audio_mute.is_mute = !openMicrophone;
  video_mute.is_init = openCamera;
  video_mute.is_mute = !openCamera;

  // 登录 RTM
  await AnyRTCLive.login(sdkAppId, userId, rtcToken, rtmToken);
  // 加入房间
  await AnyRTCLive.joinRoom(roomId, role);
  // 主播采集设备
  if (role === "host") {
    liveVideoRefs.value.addAnchorsList({
      userId,
      hasAudio: video_mute.is_exist ? openMicrophone : false,
      hasVideo: audio_mute.is_exist ? openCamera : false,
    });
    /** 摄像头、麦克风等设备 */
    if (openCamera && openMicrophone && video_mute.is_exist && audio_mute.is_exist) {
      AnyRTCLive.setCurrentCameraId(cameraList[0].deviceId);
      AnyRTCLive.setCurrentMicrophoneId(microphoneList[0].deviceId);
      speakerList.length > 0 && AnyRTCLive.setCurrentSpeakerId(speakerList[0].deviceId);
      // 打开麦克风
      await AnyRTCLive.startMediaAndPublish(`${userId}`);
    } else if (openCamera && video_mute.is_exist) {
      AnyRTCLive.setCurrentCameraId(cameraList[0].deviceId);
      // 打开摄像头
      AnyRTCLive.setVideoEncoderParam("1080p");
      await AnyRTCLive.startCameraPreview(`${userId}`);
    } else if (openMicrophone && audio_mute.is_exist) {
      AnyRTCLive.setCurrentMicrophoneId(microphoneList[0].deviceId);
      // 打开麦克风
      await AnyRTCLive.startMicrophone();
    }
  }
}

defineExpose({
  // 组件初始化
  liveInit,
});

/** 开启 token 校验后 */
// token 即将过期
const TokenWillExpired: AnyRTCLiveEvents["TokenWillExpired"] = (type) => {
  // console.log(type);
  ElMessage.warning(type + " token 即将过期，请更新 token");
  // 重新获取 token
  // .....
  // AnyRTCLive.updataToken(type,tolen)
};

// token 过期
const TokenDidExpired: AnyRTCLiveEvents["TokenDidExpired"] = (type) => {
  // console.log(type);
  ElMessage.error(type + " token 过期");
};
// token 已经过期
onMounted(() => {
  AnyRTCLive.on("TokenWillExpired", TokenWillExpired);
  AnyRTCLive.on("TokenDidExpired", TokenDidExpired);
});
onUnmounted(() => {
  AnyRTCLive.off("TokenWillExpired", TokenWillExpired);
  AnyRTCLive.off("TokenDidExpired", TokenDidExpired);
});
</script>
